package com.jxtc.enterprise.common.utils;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;



public class FeieYunPrinterApi {

    public static final String URL = "http://api.feieyun.cn/Api/Open/";//不需要修改
//    public static final String URL = "http://111.230.163.183/Api/Open/";//不需要修改

    public static final String USER = "190869871@qq.com";//*必填*：账号名
    public static final String UKEY = "pdIW7ysTMNt7KxHZ";//*必填*: 飞鹅云后台注册账号后生成的UKEY 【备注：这不是填打印机的KEY】
//    public static final String SN = "922431636";//*必填*：打印机编号，必须要在管理后台里添加打印机或调用API接口添加之后，才能调用API
//    public static final String SN = "570212717";//*必填*：打印机编号，必须要在管理后台里添加打印机或调用API接口添加之后，才能调用API
    public static final String SN = "525538933";//*必填*：打印机编号，必须要在管理后台里添加打印机或调用API接口添加之后，才能调用API
    public static final String LABEL_PRINTER_SN = "1111111";
    public static final int LINE_HEIGHT_W1H1 = 30; // 当 设置w=1，h=1 时，行高为30，整体打印效果，行与行之间 间距较为合适
    public static final int LINE_HEIGHT_W2H2 = 50; // 当 设置w=2，h=2 时，行高为50，整体打印效果，行与行之间 间距较为合适
    //**********测试时，打开下面注释掉方法的即可,更多接口文档信息,请访问官网开放平台查看**********
    public static void main(String[] args) throws Exception {
        String storeName = "口口米香-南山";
        String departName = "销售一部";
        String userName = "皮皮喵";
        String foodName = "三荤一素自选-花生猪脚-土豆烧鸡块-炒冬瓜";
        String note = "不要香菜，不吃辣椒,不要香菜，不吃辣椒，不要香菜，不吃辣椒";

        //printTicketTemplate2("525538933", storeName, foodName, "18.5", 2, "18.5",note, "18.5", "研发部茶水间","15072499385", "2024-07-10 10:11:01", userName, 9999, departName);

        // String result = print(SN, "测试店铺","小炒肉","18.8", 1, "18.8", "不要辣椒", "18.8", "龙岗云谷A1201", "15072488524","2024-07-04 11:09:24", "皮皮喵", 1234);//该接口只能是小票机使用,如购买的是标签机请使用下面方法2，调用打印

//        printLabelMsg(LABEL_PRINTER_SN, "祥瑜餐厅|FT|LKF", "运营部", "皮皮喵", "D陈皮腐乳焖鸭+农家小炒肉+时蔬:", 498 , "" , 1 , "鸿蒙智行｜鸿友总部" , "A1-1-32");
//        printVipUerTicketTemplate("570211906", "刘先生", "15072499376", "鸿蒙客户餐","【开发调试测试】公司", "皮皮喵", "享界S9T", "1/5", "2025-09-07 11:12:37");

        printVipUserOrderTicketTemplate("0000922677696", "张先生", "15072499377",
                "鸿蒙客户餐", "开发调试公司", "皮皮喵", "尚界H5", "试驾客户或潜客", "2/5", "2025-09-15 21:28:59");
    }


    public static List<String> splitLongText(String longText) {
        List<String> lines = new ArrayList<>();

        char[] chs = longText.toCharArray();
        int mod = chs.length % 12 ;
        int count = mod == 0 ? chs.length / 12 : chs.length / 12 + 1;
        int k = 0;
        for (; k < count - 1; k ++) {
            int start = (k - 1) * 12;
            int end = (k + 1) * 12;
            lines.add(longText.substring(k * 12, (k + 1) * 12));
        }
        // 最后一行，为起点开始，直到字符串结束
        lines.add(longText.substring(k * 12));
        return lines;
    }

    /**
     * 公司名称，大号字体
     * @param storeName
     * @param departName
     * @param userName
     * @param foodName
     * @param pickUpCode
     * @param note
     * @param count
     * @param companyName
     * @return
     */
    private static String labelPrinterContent1(String storeName,  String departName,
                                               String userName, String foodName, Integer pickUpCode, String note, int count, String companyName) {
        List<String> lines = splitLongText(foodName);
        String content;
        content = "<DIRECTION>1</DIRECTION>";//设定打印时出纸和打印字体的方向，n 0 或 1，每次设备重启后都会初始化为 0 值设置，1：正向出纸，0：反向出纸，
        //40mm宽度标签纸打印例子，打开注释调用标签打印接口打印
        content +=
                "<TEXT x='9' y='10' font='12' w='1' h='1' r='0'>" + storeName + "</TEXT>" +
                        "<TEXT x='9' y='40' font='12' w='1' h='1' r='0'>取餐编号：" + pickUpCode + "   份数: " + count + "</TEXT>" +
                        "<TEXT x='9' y='70' font='12' w='2' h='2' r='0'>" + departName + "</TEXT>" +
                        "<TEXT x='9' y='120' font='12' w='2' h='2' r='0'>" + companyName + "</TEXT>" +
                        "<TEXT x='9' y='170' font='12' w='2' h='2' r='0'>" + userName + "</TEXT>";
        int yPosition = 220; // 用户名占用 50个高度
        for(int k = 0 ; k < lines.size(); k ++) {
            content +="<TEXT x='9' y='" + yPosition + "' font='12' w='1' h='1' r='0'>" + lines.get(k) +"</TEXT>";
            yPosition += 30;
        }
        content +="<TEXT x='9' y='"+ yPosition +"' font='12' w='1' h='1' r='0'>备注："+ note +"</TEXT>";

        return content;
    }

    /**
     * 公司名称，小号字体
     * @param storeName
     * @param departName
     * @param userName
     * @param foodName
     * @param pickUpCode
     * @param note
     * @param count
     * @param companyName
     * @return
     */
    private static String labelPrinterContent2(String storeName,  String departName,
                                               String userName, String foodName, Integer pickUpCode, String note,
                                               int count, String companyName, String boxNo) {
        List<String> lines = splitLongText(foodName);
        String content;
        content = "<DIRECTION>1</DIRECTION>";//设定打印时出纸和打印字体的方向，n 0 或 1，每次设备重启后都会初始化为 0 值设置，1：正向出纸，0：反向出纸，
        //40mm宽度标签纸打印例子，打开注释调用标签打印接口打印
        content +=
                "<TEXT x='9' y='10' font='12' w='2' h='2' r='0'>取餐编号:" + boxNo + "</TEXT>" +
                "<TEXT x='9' y='60' font='12' w='1' h='1' r='0'>" + storeName + "</TEXT>" +
                "<TEXT x='9' y='90' font='12' w='1' h='1' r='0'>取餐码：" + pickUpCode + "   份数: " + count + "</TEXT>" +
                "<TEXT x='9' y='120' font='12' w='2' h='2' r='0'>" + departName + "</TEXT>" +
                "<TEXT x='9' y='170' font='12' w='1' h='1' r='0'>" + companyName + "</TEXT>" +
                "<TEXT x='9' y='200' font='12' w='2' h='2' r='0'>" + userName + "</TEXT>";
        int yPosition = 250; // 用户名占用 50个高度
        for(int k = 0 ; k < lines.size(); k ++) {
            content +="<TEXT x='9' y='" + yPosition + "' font='12' w='1' h='1' r='0'>" + lines.get(k) +"</TEXT>";
            yPosition += 30;
        }
        content +="<TEXT x='9' y='"+ yPosition +"' font='12' w='1' h='1' r='0'>备注："+ note +"</TEXT>";

        return content;
    }

    //方法2：贴纸 打印机
    public static String printLabelMsg(String sn, String storeName,  String departName,
                                       String userName, String foodName, Integer pickUpCode, String note, int count,
                                       String companyName, String boxNo) {
        // 公司名称，小号字体
        // todo 是否可能存在异常，导致订单打印也失败？？？
        String content = labelPrinterContent2( storeName,   departName,
                 userName,  foodName,  pickUpCode,  note,  count,  companyName, boxNo);

        System.out.println("begin_to_print_label_by_call_feie_api，sn: " + sn + ",打印内容: " + content);

        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user",USER));
        String STIME = String.valueOf(System.currentTimeMillis()/1000);
        nvps.add(new BasicNameValuePair("stime",STIME));
        nvps.add(new BasicNameValuePair("sig",signature(USER,UKEY,STIME)));
        nvps.add(new BasicNameValuePair("apiname","Open_printLabelMsg"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("sn",sn));
        nvps.add(new BasicNameValuePair("content",content));
        nvps.add(new BasicNameValuePair("times","1"));//打印联数

        CloseableHttpResponse response = null;
        String result = null;
        try
        {
            post.setEntity(new UrlEncodedFormEntity(nvps,"utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if(statecode == 200){
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null){
                    //服务器返回的JSON字符串，建议要当做日志记录起来
                    result = EntityUtils.toString(httpentity);
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
        finally{
            try {
                if(response!=null){
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;

    }

    // 小票打印，样式2，给公司包餐场景，使用小票打印机打印
    public static String printTicketTemplate2(String sn, String storeName, String printFoodName,String printFoodSalePrice,
                                              int foodCount,String oneFoodTotalPrice,String note,String orderTotalPrice,
                                              String address,String phoneNumber,String createTime,
                                               String userName, Integer pickUpCode, String departName) {
        //标签说明：
        //单标签:
        //"<BR>"为换行,"<CUT>"为切刀指令(主动切纸,仅限切刀打印机使用才有效果)
        //"<LOGO>"为打印LOGO指令(前提是预先在机器内置LOGO图片),"<PLUGIN>"为钱箱或者外置音响指令
        //成对标签：
        //"<CB></CB>"为居中放大一倍,"<B></B>"为放大一倍,"<C></C>"为居中,<L></L>字体变高一倍
        //<W></W>字体变宽一倍,"<QR></QR>"为二维码,"<BOLD></BOLD>"为字体加粗,"<RIGHT></RIGHT>"为右对齐
        //拼凑订单内容时可参考如下格式
        //根据打印纸张的宽度，自行调整内容的格式，可参考下面的样例格式
        final int CHARS_OF_ONE_LINE = 5;
        int lastLineChars = printFoodName.length() % CHARS_OF_ONE_LINE;
        int lineCount = lastLineChars == 0 ? printFoodName.length() / CHARS_OF_ONE_LINE : printFoodName.length() / CHARS_OF_ONE_LINE + 1;
        List<String> lines = new ArrayList<>();
        for (int k = 0 ; k < lineCount ; k ++) {
            int startIdx = k * CHARS_OF_ONE_LINE ;
            int endIdx = (k + 1) * CHARS_OF_ONE_LINE > printFoodName.length() ? printFoodName.length() : (k + 1) * CHARS_OF_ONE_LINE;
            lines.add(printFoodName.substring(startIdx, endIdx));
        }
        String content;
        content = "<CB>" + storeName + "</CB><BR>";
        content += "<CB>取餐编号：" + pickUpCode + "</CB><BR>";
        content += "<CB>用户: " + userName + "</CB><BR>";
        content += "<CB>部门: " + departName + "</CB><BR>";
        content += "联系电话：" + phoneNumber + "<BR>";

        content += "餐品　　　　　           数量  <BR>";
        content += "--------------------------------<BR>";
        String paddedLine = padString2(lines.get(0), CHARS_OF_ONE_LINE);
        content += "<B>" +paddedLine + " 【" + foodCount + "份】</B><BR>" ;
        for (int k = 1 ; k < lineCount; k ++) {
            paddedLine = padString2(lines.get(k), CHARS_OF_ONE_LINE);
            content += "<B>" + paddedLine + " </B><BR>";
        }
        content += "<BR><BR><BR><BR><BR>";
        content += "--------------------------------<BR>";
        content += "备注：" + note + "<BR>";
        content += "--------------------------------<BR>";

        content += "送货地点：" + address + "<BR>";
        // 每一行最大打印15个汉字，此处可以不进行分行，打印机会自动换行，当汉字超过15个，或字母，数字超过一定个数（没有实际验证过），打印机打印时会自动换行
//        for (int idx = 0 ; idx < addressMsg.length(); idx += 15) {
//            int startIdx = idx ;
//            int endIdx = idx + 15 > addressMsg.length() ? addressMsg.length() : idx + 15;
//            content += addressMsg.substring(startIdx, endIdx) + "<BR>";
//        }

        content += "订餐时间："+ createTime +"<BR>";
//        content += "<QR>http://www.baidu.com</QR>";
        System.out.println("begin_to_print_ticket_by_call_feie_api，sn: " + sn + ",打印内容: " + content);
        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user", USER));
        String STIME = String.valueOf(System.currentTimeMillis() / 1000);
        nvps.add(new BasicNameValuePair("stime", STIME));
        nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
        nvps.add(new BasicNameValuePair("apiname", "Open_printMsg"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("sn", sn));
        nvps.add(new BasicNameValuePair("content", content));
        nvps.add(new BasicNameValuePair("times", "1"));//打印联数
        nvps.add(new BasicNameValuePair("backurl ", "https://customer.qiyetuancan.com:3389/jeecg-boot/"));//打印联数

        CloseableHttpResponse response = null;
        String result = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if (statecode == 200) {
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null) {
                    //服务器返回的JSON字符串，建议要当做日志记录起来
                    result = EntityUtils.toString(httpentity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    private static String padString2(String orginStr, int expectedLength) {
        StringBuffer oneLine = new StringBuffer(32);
        oneLine.append(orginStr);
        if (orginStr.length() <= expectedLength) {
            // 空格的位宽 比单个函数要窄，因此需要两个空格
            for (int m = 0 ; m < (expectedLength - orginStr.length()) * 2 ; m ++) {
                oneLine.append(" ");
            }
        }
        // 如果填充太多空格，会导致行末尾的 金额列打印到第二列
        if (oneLine.length() > 7) {
            return oneLine.substring(0, 7);
        } else {
            return oneLine.toString();
        }
    }

    //方法1: 打印标签
    public static String print(String sn, String storeName, String printFoodName, String foodPrice, Integer foodCount, String foodTotalPrice
            , String notes, String orderTotalPrice, String address, String phone, String createTime, String nickName, Integer pickUpNum) {
        //标签说明：
        //单标签:
        //"<BR>"为换行,"<CUT>"为切刀指令(主动切纸,仅限切刀打印机使用才有效果)
        //"<LOGO>"为打印LOGO指令(前提是预先在机器内置LOGO图片),"<PLUGIN>"为钱箱或者外置音响指令
        //成对标签：
        //"<CB></CB>"为居中放大一倍,"<B></B>"为放大一倍,"<C></C>"为居中,<L></L>字体变高一倍
        //<W></W>字体变宽一倍,"<QR></QR>"为二维码,"<BOLD></BOLD>"为字体加粗,"<RIGHT></RIGHT>"为右对齐
        //拼凑订单内容时可参考如下格式
        //根据打印纸张的宽度，自行调整内容的格式，可参考下面的样例格式

        int lastLineChars = printFoodName.length() % 7;
        int lineCount = lastLineChars == 0 ? printFoodName.length() / 7 : printFoodName.length() / 7 + 1;
        List<String> lines = new ArrayList<>();
        for (int k = 0 ; k < lineCount ; k ++) {
            int startIdx = k * 7 ;
            int endIdx = (k + 1) * 7 > printFoodName.length() ? printFoodName.length() : (k + 1) * 7;
            lines.add(printFoodName.substring(startIdx, endIdx));
        }
        String content;
        content = "<CB>" + storeName + "</CB><BR>";
        content += "<CB>取餐编号：" + pickUpNum + "</CB><BR>";
        content += "<CB>用户: " + nickName + "</CB><BR>";
        content += "联系电话：" + phone + "<BR>";

        content += "餐品　　　　　 单价  数量 金额<BR>";
        content += "--------------------------------<BR>";
        String paddedLine = padString(lines.get(0), 7);
        content += paddedLine + " " + foodPrice + "    " + foodCount + "  "+  foodTotalPrice + "<BR>" ;
        for (int k = 1 ; k < lineCount; k ++) {
            paddedLine = padString(lines.get(k), 7);
            content += paddedLine + " <BR>";
        }
        content += "<BR><BR><BR><BR><BR>";
        content += "--------------------------------<BR>";
        content += "备注：" + notes + "<BR>";
        content += "--------------------------------<BR>";

        content += "合计：" + orderTotalPrice + " 元<BR>";
        content += "余额或积分抵扣：" + orderTotalPrice + " 元<BR>";
        content += "实际支付：" + orderTotalPrice + " 元<BR>";
        content += "送货地点：" + address + "<BR>";
        // 每一行最大打印15个汉字，此处可以不进行分行，打印机会自动换行，当汉字超过15个，或字母，数字超过一定个数（没有实际验证过），打印机打印时会自动换行
//        for (int idx = 0 ; idx < addressMsg.length(); idx += 15) {
//            int startIdx = idx ;
//            int endIdx = idx + 15 > addressMsg.length() ? addressMsg.length() : idx + 15;
//            content += addressMsg.substring(startIdx, endIdx) + "<BR>";
//        }

        content += "订餐时间："+ createTime +"<BR>";
//        content += "<QR>http://www.baidu.com</QR>";

        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user", USER));
        String STIME = String.valueOf(System.currentTimeMillis() / 1000);
        nvps.add(new BasicNameValuePair("stime", STIME));
        nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
        nvps.add(new BasicNameValuePair("apiname", "Open_printMsg"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("sn", sn));
        nvps.add(new BasicNameValuePair("content", content));
        nvps.add(new BasicNameValuePair("times", "1"));//打印联数
        nvps.add(new BasicNameValuePair("backurl ", "https://customer.qiyetuancan.com:3389/jeecg-boot/"));//打印联数

        CloseableHttpResponse response = null;
        String result = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if (statecode == 200) {
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null) {
                    //服务器返回的JSON字符串，建议要当做日志记录起来
                    result = EntityUtils.toString(httpentity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }

    private static String padString(String orginStr, int expectedLength) {
        StringBuffer oneLine = new StringBuffer(16);
        oneLine.append(orginStr);
        if (orginStr.length() <= expectedLength) {
            // 空格的位宽 比单个函数要窄，因此需要两个空格
            for (int m = 0 ; m < (expectedLength - orginStr.length()) * 2 ; m ++) {
                oneLine.append(" ");
            }
        }
        // 如果填充太多空格，会导致行末尾的 金额列打印到第二列
        if (oneLine.length() > 9) {
            return oneLine.substring(0, 9);
        } else {
            return oneLine.toString();
        }
    }

    //方法3
    public static String queryOrderState(String orderid) {

        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user", USER));
        String STIME = String.valueOf(System.currentTimeMillis() / 1000);
        nvps.add(new BasicNameValuePair("stime", STIME));
        nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
        nvps.add(new BasicNameValuePair("apiname", "Open_queryOrderState"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("orderid", orderid));

        CloseableHttpResponse response = null;
        String result = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if (statecode == 200) {
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null) {
                    //服务器返回
                    result = EntityUtils.toString(httpentity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        System.out.println("queryOrderState: " + result);
        return result;

    }

    //生成签名字符串
    private static String signature(String USER, String UKEY, String STIME) {
        String s = DigestUtils.sha1Hex(USER + UKEY + STIME);
        return s;
    }

    /**
     * 此方法为 打印 贴纸类型的 标签
     * 贴纸 ，贴纸背面有胶水，可以粘贴在 餐盒上；
     * 小票，外卖小票，背面没有胶水，需要 使用 透明胶或订书机 订在包装袋上，通常的 外卖使用的是 外卖小票
     * @return
     */
    public static String printVipUserOrderLabelTemplate(String sn,
                                                        String vipUsername, String vipUserPhone, String vipUserMealSetName,
                                                        String serviceCompanyName, String serviceEmployeeName,
                                                        String vipUserCarType, String orderCount, String createVipOrderTime) {
        //标签说明：
        //单标签:
        //"<BR>"为换行,"<CUT>"为切刀指令(主动切纸,仅限切刀打印机使用才有效果)
        //"<LOGO>"为打印LOGO指令(前提是预先在机器内置LOGO图片),"<PLUGIN>"为钱箱或者外置音响指令
        //成对标签：
        //"<CB></CB>"为居中放大一倍,"<B></B>"为放大一倍,"<C></C>"为居中,<L></L>字体变高一倍
        //<W></W>字体变宽一倍,"<QR></QR>"为二维码,"<BOLD></BOLD>"为字体加粗,"<RIGHT></RIGHT>"为右对齐

        String content;
        content = "<DIRECTION>1</DIRECTION>";//设定打印时出纸和打印字体的方向，n 0 或 1，每次设备重启后都会初始化为 0 值设置，1：正向出纸，0：反向出纸，
        int y = 10;
        String vipUserNameLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>客户: %s</TEXT>", y, vipUsername);
        content += vipUserNameLine;
        y += LINE_HEIGHT_W1H1;
        String vipUserPhoneLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>客户手机号: %s</TEXT>", y, vipUserPhone);
        content += vipUserPhoneLine;
        y += LINE_HEIGHT_W1H1;
        String vipUserMealSetNameLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>套餐名称: %s</TEXT>", y, vipUserMealSetName);
        content += vipUserMealSetNameLine;
        y += LINE_HEIGHT_W1H1;
        String serviceCompanyNameLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>公司名称: %s</TEXT>", y, serviceCompanyName);
        content += serviceCompanyNameLine;
        y += LINE_HEIGHT_W1H1;
        String serviceEmployeeNameLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>接待员工: %s</TEXT>", y, serviceEmployeeName);
        content += serviceEmployeeNameLine;
        y += LINE_HEIGHT_W1H1;
        String vipUserCarTypeLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>车型: %s</TEXT>", y, vipUserCarType);
        content += vipUserCarTypeLine;
        y += LINE_HEIGHT_W1H1;
        // 如：第 1/3 份 (3 份中的第 1 份)
        String orderCountLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>第 %s 份</TEXT>", y, orderCount);
        content += orderCountLine;
        y += LINE_HEIGHT_W1H1;
        String createVipOrderTimeLine = String.format("<TEXT x='9' y='%d' font='12' w='1' h='1' r='0'>时间: %s </TEXT>", y, createVipOrderTime);
        content += createVipOrderTimeLine;

        System.out.println("begin_to_print_ticket_by_call_feie_api，sn: " + sn + ", 打印内容: " + content);
        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user", USER));
        String STIME = String.valueOf(System.currentTimeMillis() / 1000);
        nvps.add(new BasicNameValuePair("stime", STIME));
        nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
        // 贴纸打印：Open_printLabelMsg； 外卖小票：Open_printMsg
        nvps.add(new BasicNameValuePair("apiname", "Open_printLabelMsg"));
        nvps.add(new BasicNameValuePair("sn", sn));
        nvps.add(new BasicNameValuePair("content", content));
        nvps.add(new BasicNameValuePair("times", "1"));//打印联数
        nvps.add(new BasicNameValuePair("backurl ", "https://customer.qiyetuancan.com:3389/jeecg-boot/"));//打印联数

        CloseableHttpResponse response = null;
        String result = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if (statecode == 200) {
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null) {
                    //服务器返回的JSON字符串，建议要当做日志记录起来
                    result = EntityUtils.toString(httpentity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }



    /**
     * 此方法为 打印 小票 类型的 标签
     * 贴纸 ，贴纸背面有胶水，可以粘贴在 餐盒上；
     * 小票，外卖小票，背面没有胶水，需要 使用 透明胶或订书机 订在包装袋上，通常的 外卖使用的是 外卖小票
     * @return
     */
    public static String printVipUserOrderTicketTemplate(String sn,
                                                        String vipUsername, String vipUserPhone, String vipUserMealSetName,
                                                        String serviceCompanyName, String serviceEmployeeName,
                                                        String vipUserCarType, String vipUserType, String orderCount, String createVipOrderTime) {
        //标签说明：
        //单标签:
        //"<BR>"为换行,"<CUT>"为切刀指令(主动切纸,仅限切刀打印机使用才有效果)
        //"<LOGO>"为打印LOGO指令(前提是预先在机器内置LOGO图片),"<PLUGIN>"为钱箱或者外置音响指令
        //成对标签：
        //"<CB></CB>"为居中放大一倍,"<B></B>"为放大一倍,"<C></C>"为居中,<L></L>字体变高一倍
        //<W></W>字体变宽一倍,"<QR></QR>"为二维码,"<BOLD></BOLD>"为字体加粗,"<RIGHT></RIGHT>"为右对齐
        //拼凑订单内容时可参考如下格式
        //根据打印纸张的宽度，自行调整内容的格式，可参考下面的样例格式
        String content;
        content = "<CB>鸿蒙智行</CB><BR>";
        content += "<CB>      </CB><BR>";
        content += "<CB>客户: " + vipUsername + "</CB><BR>";
        content += "<CB>" + vipUserPhone + "</CB><BR>";
        content += "<B>   </B><BR>";
        content += "套餐名称: " + vipUserMealSetName + "<BR>";
        content += "   <BR>";
        content += "公司名称: " + serviceCompanyName + "<BR>";
        content += "   <BR>";
        content += "接待员工: " + serviceEmployeeName + "<BR>";
        content += "   <BR>";
        content += "车型: " + vipUserCarType + "<BR>";
        content += "   <BR>";
        content += "客户: " + vipUserType + "<BR>";
        content += "   <BR>";
        content += "出餐: " + orderCount + "<BR>";
        content += "   <BR>";
        content += "时间: " + createVipOrderTime + "<BR>";
        content += "   <BR>";

        content +="全新问界M7开启预订，预售价28.8万起。预订全新问界M7可享2000元意向金抵5000元购车尾款权益<BR>";
        content += "   <BR>";
        content += "   <BR>";

        System.out.println("printVipUserOrderTicketTemplate begin_to_print_ticket_by_call_feie_api，sn: " + sn + ",打印内容: " + content);
        //通过POST请求，发送打印信息到服务器
        RequestConfig requestConfig = RequestConfig.custom()
                .setSocketTimeout(30000)//读取超时
                .setConnectTimeout(30000)//连接超时
                .build();

        CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .build();

        HttpPost post = new HttpPost(URL);
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("user", USER));
        String STIME = String.valueOf(System.currentTimeMillis() / 1000);
        nvps.add(new BasicNameValuePair("stime", STIME));
        nvps.add(new BasicNameValuePair("sig", signature(USER, UKEY, STIME)));
        nvps.add(new BasicNameValuePair("apiname", "Open_printMsg"));//固定值,不需要修改
        nvps.add(new BasicNameValuePair("sn", sn));
        nvps.add(new BasicNameValuePair("content", content));
        nvps.add(new BasicNameValuePair("times", "1"));//打印联数
        nvps.add(new BasicNameValuePair("backurl ", "https://customer.qiyetuancan.com:3389/jeecg-boot/"));//打印联数

        CloseableHttpResponse response = null;
        String result = null;
        try {
            post.setEntity(new UrlEncodedFormEntity(nvps, "utf-8"));
            response = httpClient.execute(post);
            int statecode = response.getStatusLine().getStatusCode();
            if (statecode == 200) {
                HttpEntity httpentity = response.getEntity();
                if (httpentity != null) {
                    //服务器返回的JSON字符串，建议要当做日志记录起来
                    result = EntityUtils.toString(httpentity);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                post.abort();
            } catch (Exception e) {
                e.printStackTrace();
            }
            try {
                httpClient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return result;
    }
}